<template>
  <el-card>
    <div slot="header" class="clearfix">
      <span>序列流属性</span>
    </div>
    <el-form-item label="编号">
      <el-input v-model="id" />
    </el-form-item>
    <el-form-item label="名称">
      <el-input v-model="name" />
    </el-form-item>
    <el-form-item v-show="needConditiona" label="跳转条件">
      <el-input v-model="condition" readonly @focus="openDialog" />
    </el-form-item>
    <SelectDialog title="跳转条件配置" :append-to-body="true" :show="dialogTableVisible" @on-ok="saveConditions" @on-cancel="dialogTableVisible = false">
      <el-row>
        <el-col :span="12">
          <el-table :data="table.conditions" border height="300" :highlight-current-row="true" @row-click="selectRow">
            <el-table-column type="index" width="50" label="序号" />
            <el-table-column property="variableLabel" label="变量" />
            <el-table-column property="conditionalOptLabel" label="判断条件" />
            <el-table-column property="conditionalValLabel" label="值" />
            <el-table-column property="logicLabel" label="逻辑" />
          </el-table>
          <div style="textAlign:right">
            <el-button-group style="margin-left:5px;margin-right:0px;margin-top:8px">
              <el-button type="primary" icon="el-icon-minus" @click="removeRow" />
              <el-button type="primary" icon="el-icon-plus" @click="addRow" />
            </el-button-group>
          </div>
        </el-col>
        <el-col :span="11" :offset="1">
          <div v-if="formShow === true">
            <el-form label-width="auto" size="mini" label-position="top">
              <el-form-item label="变量">
                <el-select v-model="form.variable" clearable filterable allow-create default-first-option placeholder="请选择">
                  <el-option v-for="item in conditionList" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                </el-select>
              </el-form-item>
              <el-form-item label="判断条件">
                <el-select v-model="form.conditionalOpt" placeholder="请选择">
                  <el-option v-for="item in conditionalOpts" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                </el-select>
              </el-form-item>
              <el-form-item label="值">
                <AdapterComponent v-model="form.conditionalVal" :type="form.tmp.componentType" :data="form.tmp.conditionalValData" />
              </el-form-item>
              <el-form-item label="逻辑">
                <el-select v-model="form.logic" placeholder="请选择">
                  <el-option v-for="item in logicOptions" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                </el-select>
              </el-form-item>
            </el-form>
          </div>
          <div v-else>
            未选择条件
          </div>
        </el-col>
      </el-row>
    </SelectDialog>
  </el-card>
</template>
<script>
import SelectDialog from '@neu/biz-core/components/SelectDialog'
import bpmnHelper from '../js/helper/BpmnHelper'
import { isBlank } from '../js/util/CommonUtils'
import { fieldList } from '@neu/dcam-ui/api/workflowForm'
import { OperatorAllOptions, LogicOptions } from '../js/const/bpmnConsts.js'
import AdapterComponent from '../assistComponents/AdapterComponent.vue'
const eventDefinitionHelper = require('../js/helper/EventDefinitionHelper')
const elementHelper = require('../js/helper/ElementHelper')
const uuid = require('uuid/v1')
const DEFAULT_VALUE = {
  condition: '未配置任何条件',
  logicLabel: '无'
}
const conditionList = [{
  VALUE: 'pass/total',
  TEXT: '多实例条件-通过比例'
}, {
  VALUE: 'refuse/total',
  TEXT: '多实例条件-拒绝比例'
}, {
  VALUE: 'nrOfCompletedInstances/nrOfInstances',
  TEXT: '多实例条件-完成比例'
}, {
  VALUE: 'pass',
  TEXT: '多实例条件-通过人数'
}, {
  VALUE: 'refuse',
  TEXT: '多实例条件-拒绝人数'
}, {
  VALUE: 'nrOfCompletedInstances',
  TEXT: '多实例条件-完成人数'
}]
export default {
  components: {
    AdapterComponent,
    SelectDialog
  },
  props: {
    element: {
      required: false,
      type: Object,
      default: null
    }
  },
  inject: ['bpmnModeler'],
  data() {
    return {
      modeling: null,
      id: this.element.id || '',
      name: '',
      condition: DEFAULT_VALUE.condition,
      // defaultflow:false,
      // 时都需要条件
      needConditiona: false,
      dialogTableVisible: false,
      // 条件列表
      conditionList: [...conditionList],
      logicOptions: LogicOptions,
      conditionalOpts: [],
      formShow: false,
      form: {
        id: '',
        variable: '',
        conditionalOpt: '',
        conditionalVal: '',
        logic: null,
        tmp: {
          // 变量的详细信息
          variableInfo: undefined,
          componentType: 'input',
          conditionalValData: undefined
        }
      },
      table: {
        conditions: [],
        selectedRow: undefined
      },
      /** source 的form */
      formKey: null

    }
  },
  watch: {
    element: {
      deep: true,
      immediate: true,
      handler(element, oldVal) {
        this.name = element.businessObject.name
        // 显示条件配置选项
        this.needConditiona = true
        // this.defaultflow = false;
        // 获取source节点
        const sourceBo = bpmnHelper.getBo(element.source)

        if (!sourceBo) {
          return
        }
        const sourceFormKey = sourceBo.formKey
        if (sourceFormKey) {
          this.formKey = sourceFormKey
          // console.log(sourceFormKey)
        }
        // 获取source上的默认连线
        // let defalutSequence = element.businessObject.get('defaultflow');
        // if(defalutSequence){
        //     this.defaultflow = true;
        // }
        // 加载条件
        this.loadCondition()
      }
    },
    name: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, {
          name: newVal
        })
      }
    },
    // condition: {
    //   handler(newVal, oldVal) {
    //     this.modeling.updateProperties(this.element, {
    //       'condition': newVal
    //     })
    //   }
    // },
    // defaultflow(newVal,oldVal){
    //     if(!this.element.source){
    //         return;
    //     }

    //     this.modeling.updateProperties(this.element, {
    //         'defaultflow': newVal
    //     })
    // },
    // 监控变量的值
    'form.variable': {
      immediate: true,
      handler: function(newVal, oldVal) {
        if (newVal === '') {
          return
        }
        const variableInfo = this.getVariableInfo(newVal)
        // 初始化组组件的值
        this.initSubComponent(variableInfo)
        if (variableInfo) {
          const currentRow = this.table.selectedRow
          const index = this.table.conditions.findIndex(item => { return item.id === currentRow.id })
          currentRow.variable = newVal
          currentRow.variableLabel = variableInfo.TEXT
          this.$set(this.table.conditions, index, currentRow)
        }
      }
    },
    'form.conditionalOpt': function(newVal, oldVal) {
      const variableInfo = this.getVariableInfo()
      const currentRow = this.table.selectedRow
      if (currentRow) {
        if (variableInfo) {
          const index = this.table.conditions.findIndex(item => { return item.id === currentRow.id })
          currentRow.conditionalOpt = newVal
          const opt = OperatorAllOptions.find((item) => { return item.VALUE === newVal })
          if (opt) {
            currentRow.conditionalOptLabel = opt.TEXT
          }
          this.$set(this.table.conditions, index, currentRow)
        }
      }
    },
    'form.conditionalVal': function(newVal, oldVal) {
      if (newVal !== oldVal) {
        const variableInfo = this.getVariableInfo()
        const currentRow = this.table.selectedRow
        if (currentRow) {
          if (variableInfo) {
            const index = this.table.conditions.findIndex(item => { return item.id === currentRow.id })
            currentRow.conditionalVal = newVal
            currentRow.conditionalValLabel = newVal
            this.$set(this.table.conditions, index, currentRow)
          }
        }
      }
    },
    'form.logic': {
      immediate: true,
      handler: function(newVal, oldVal) {
        const currentRow = this.table.selectedRow
        if (currentRow) {
          const index = this.table.conditions.findIndex(item => { return item.id === currentRow.id })
          if (newVal !== oldVal) {
            currentRow.logic = newVal
            if (newVal === '') {
              currentRow.logicLabel = '无'
            } else {
              const logicOpt = LogicOptions.find((item) => { return item.VALUE === newVal })
              if (logicOpt) {
                currentRow.logicLabel = logicOpt.TEXT
              }
            }
            this.$set(this.table.conditions, index, currentRow)
          }
        }
      }
    },
    'table.selectedRow': {
      deep: true,
      immediate: true,
      handler: function(newVal) {
        if (newVal !== undefined) {
          this.formShow = true
          this.form.variable = newVal.variable
          const variableInfo = this.getVariableInfo()
          this.initSubComponent(variableInfo)
          this.form.conditionalOpt = newVal.conditionalOpt
          this.form.conditionalVal = newVal.conditionalVal
          this.form.logic = newVal.logic
          this.form.tmp.variableInfo = undefined
        } else {
          this.formShow = false
        }
      }
    },
    'table.conditions': {
      immediate: true,
      handler: function(conditions) {
        if (conditions === undefined || conditions.length === 0) {
          this.condition = '未配置任何条件'
        } else {
          this.condition = '已配置' + conditions.length + '条件'
        }
      }
    }
    // formKey: {
    //   immediate: true,
    //   handler: function(newVal) {
    //     if (newVal) {
    //       this.loadCanditionList()
    //     }
    //   }
    // }
  },

  mounted() {
    const bpmnModeler = this.bpmnModeler()
    this.modeling = bpmnModeler.get('modeling')
  },

  methods: {
    openDialog() {
      this.table.conditions = []
      this.table.selectedRow = undefined
      this.form.tmp.componentType = 'input'
      this.loadCondition()
      // 翻译
      this.translateAllConditions()
      this.dialogTableVisible = true
    },
    closeDialog() {
      const bo = bpmnHelper.getBo(this.element)
      this.loadCondition(bo)
    },
    selectRow(row, column, event) {
      this.table.selectedRow = row
    },
    addRow() {
      this.table.conditions.push({
        id: uuid(),
        variable: '',
        variableLabel: '',
        conditionalOpt: '',
        conditionalOptLabel: '',
        conditionalVal: '',
        conditionalValLabel: '',
        logic: '',
        logicLabel: ''
      })
    },
    // 保存条件
    saveConditions() {
      const conditions = this.table.conditions
      let conditionExpress = ''
      if (this.validateConditions(conditions)) {
        conditions.forEach((condition, index) => {
          const conditionalVal = '"' + condition.conditionalVal + '"'
          if (index === conditions.length - 1 || conditions.length === 1) {
            conditionExpress += condition.variable + condition.conditionalOpt + conditionalVal
          } else {
            conditionExpress += condition.variable + condition.conditionalOpt + conditionalVal + ' ' + condition.logic + ' '
          }
        })
        // 以下代码是校验配置条件是否存在于this.conditionList中。现已改成可手动输入，故先注释掉
        // const conditionList = this.conditionList
        // forEach(conditions, function(condition, index) {
        //   const conditionInfo = find(conditionList, { VALUE: condition.variable })
        //   if (conditionInfo) {
        //     let conditionalVal
        //     if (conditionInfo.type !== 'number') {
        //       conditionalVal = '"' + condition.conditionalVal + '"'
        //     }
        //     if (index === conditions.length - 1 || conditions.length === 1) {
        //       conditionExpress += condition.variable + condition.conditionalOpt + conditionalVal
        //     } else {
        //       conditionExpress += condition.variable + condition.conditionalOpt + conditionalVal + ' ' + condition.logic + ' '
        //     }
        //   }
        // })
        let conditionOrConditionExpression
        const bo = bpmnHelper.getBo(this.element)
        const bpmnModeler = this.bpmnModeler()
        const commandStack = bpmnModeler.get('commandStack')
        if (conditionExpress.length > 0) {
          const conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(this.element)

          const bpmnFactory = bpmnModeler.get('bpmnFactory')

          // 生成表达式
          conditionExpress = '${' + conditionExpress + '}'
          // 设置表达式的值
          conditionOrConditionExpression = elementHelper.createElement(
            'bpmn:FormalExpression',
            { body: conditionExpress },
            conditionalEventDefinition || bo,
            bpmnFactory
          )
          // const source = this.element.source
          // 如果是默认条线，移除source的属性
          // if (source && source.businessObject.defaultflow) {
          //     bpmnHelper.updatePropertiesByCmd(source,commandStack,{ 'defaultflow': false });
          // }
        }
        bpmnHelper.updatePropertiesByCmd(this.element, commandStack, { conditionExpression: conditionOrConditionExpression })
        this.dialogTableVisible = false
      }
    },
    removeRow() {
      if (this.table.selectedRow !== undefined) {
        // 删除选定的数组
        const index = this.table.conditions.findIndex(item => { return item.id === this.table.selectedRow.id })
        this.table.conditions.splice(index, 1)
        this.table.selectedRow = undefined
      }
    },
    loadCondition(bo) {
      bo = bo || bpmnHelper.getBo(this.element)
      const conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(this.element)
      const conditionExpression = conditionalEventDefinition ? conditionalEventDefinition.condition : bo.conditionExpression
      this.condition = '未配置任何条件'
      if (conditionExpression) {
        // 获取配置的条件表达
        const condition = conditionExpression.get('body')
        this.parseCondition(condition)
      }
    },
    parseCondition(conditionExpress) {
      const operators = ['!', '=', '>', '<']
      const logicOperators = ['&', '|']
      conditionExpress = conditionExpress.replace('$', '').replace('{', '').replace('}', '').replace(new RegExp('"', 'g'), '')
      this.table.conditions = []
      const self = this
      splitConditionExpress(conditionExpress)
      // 截取表达时候
      function splitConditionExpress(str) {
        // 正查找查找操作符
        const idx = findChar(str, true, true, logicOperators)
        if (idx === -1) {
          const row = createConditionRow(str)
          self.table.conditions.push(row)
          return
        } else {
          // 操作符
          const logic = str.substring(idx, idx + 2)
          const conditionExpress = str.substring(0, idx)
          const row = createConditionRow(conditionExpress, logic)
          self.table.conditions.push(row)
          const newStr = str.substring(idx + 2)
          splitConditionExpress(newStr)
        }
      }
      function createConditionRow(conditionExpress, logic) {
        const row = {}
        // 纯表达式
        const headOptIdx = findChar(conditionExpress, true, false, operators)
        const footOptIdx = findChar(conditionExpress, false, false, operators)
        // 变量
        const variable = conditionExpress.substring(0, headOptIdx).trim()
        // 值
        const val = conditionExpress.substring(footOptIdx + 1, conditionExpress.length).trim()
        // 操作符
        const opt = conditionExpress.substring(headOptIdx, footOptIdx + 1).trim()
        row.id = uuid()
        row.variable = variable
        row.conditionalOpt = opt
        row.conditionalVal = val
        row.logic = logic
        return row
      }
      /**
             * @description 检索第一个的操作操作符
             * @param str 需要被检索的字符串
             * @param  type 类型 true:正查找 false:反查找
             * @param report 检索的字符是否需要重复 true | false
             */
      function findChar(str, type, report, operators) {
        let index = -1
        const len = str.length
        if (type) {
          for (let i = 0; i < len; i++) {
            const char = str.charAt(i)
            if (operators.includes(char)) {
              // 查找第一个
              if (report) {
                if (char === str.charAt(i + 1)) {
                  index = i
                  break
                }
              } else {
                index = i
                break
              }
            }
          }
        } else if (!type) {
          for (let i = (len - 1); i >= 0; i--) {
            const char = str.charAt(i)
            if (operators.includes(char)) {
              // 从末尾查找最后一个
              if (report) {
                if (char === str.charAt(i - 1)) {
                  index = i
                  break
                }
              } else {
                index = i
                break
              }
            }
          }
        }
        return index
      }
    },
    loadCanditionList() {
      // 根据formkey获得字段
      this.conditionList = [...conditionList]
      const that = this
      if (this.formKey) {
        const obj = {
          s_formCode: this.formKey
        }
        fieldList(obj).then(res => {
          if (res.status === 'success') {
            res.data.forEach(t => {
              const obj = {
                VALUE: t.nodeKey,
                TEXT: t.name
              }
              that.conditionList.push(obj)
            })
          }
        })
        // const multiObj = {
        //   VALUE: 'pass/total',
        //   TEXT: '多实例条件'
        // }
        // that.conditionList.push(multiObj)
      }
    },
    // 设置组件的值
    initSubComponent(variableInfo) {
      variableInfo = variableInfo || this.getVariableInfo()
      if (variableInfo) {
        // 应该按照类型显示控件todo
        // this.conditionalOpts = []
        this.conditionalOpts = OperatorAllOptions
        // this.form.tmp.componentType = 'select'
        // this.form.tmp.conditionalValData = wfResult
      }
    },
    translateAllConditions() {
      const conditions = this.table.conditions
      conditions.forEach((condition) => {
        const conditionInfo = this.getVariableInfo(condition.variable)
        if (conditionInfo) {
          // 翻译变量名称
          condition.variableLabel = conditionInfo.TEXT
          // 如果条件类型为结果类型的
          // if (conditionInfo.type === 'result') {
          //   // 翻译条件值
          //   const resultInfo = find(wfResult, { VALUE: condition.conditionalVal })
          //   condition.conditionalValLabel = resultInfo.TEXT
          // }
          condition.conditionalValLabel = condition.conditionalVal
        }
        const optInfo = OperatorAllOptions.find((item) => { return item.VALUE === condition.conditionalOpt })
        if (optInfo) {
          // 翻译操作符
          condition.conditionalOptLabel = optInfo.TEXT
        }
        const logicInfo = LogicOptions.find((item) => { return item.VALUE === condition.logic })
        if (logicInfo) {
          // 翻译逻辑符
          condition.logicLabel = logicInfo.TEXT
        } else {
          condition.logicLabel = '无'
        }
      })
    },
    getVariableInfo(variableVal) {
      if (variableVal === undefined) {
        variableVal = this.form.variable
      }
      const text = this.conditionList.find(function(item) { return item.VALUE === variableVal })
      if (text !== undefined) {
        return text
      } else {
        return {
          VALUE: variableVal,
          TEXT: variableVal
        }
      }
    },
    // 校验表达式的正确性
    validateConditions(conditions) {
      const that = this
      let flag = true
      conditions.forEach((condition, index) => {
        if (!flag) return
        if (isBlank(condition.variable)) {
          that.$message({
            showClose: true,
            message: '第' + (index + 1) + '个条件,变量不能为空',
            type: 'error'
          })
          flag = false
          return
        }
        if (isBlank(condition.conditionalOpt)) {
          that.$message({
            showClose: true,
            message: '第' + (index + 1) + '个条件,操作符不能为空',
            type: 'error'
          })
          flag = false
          return
        }
        if (isBlank(condition.conditionalVal)) {
          that.$message({
            showClose: true,
            message: '第' + (index + 1) + '个条件,变量值不能为空',
            type: 'error'
          })
          flag = false
          return
        }
        if (index + 1 < conditions.length) {
          if (isBlank(condition.logic)) {
            that.$message({
              showClose: true,
              message: '配置多个条件时，须配置逻辑,第' + (index + 1) + '个条件逻辑未配置',
              type: 'error'
            })
            flag = false
            return
          }
        }
      })
      return flag
    }
  }
}
</script>
<style>

</style>
